package websocket

import (
	"fmt"
	"net"
	"strings"
)

/*
Websocket struct
*/
type WebSocket struct {
	connList []*Conn
	CallBack func(msg string, c *Conn)
	close    chan int
	hello    string
}

/*
SocketSource Socket 资源接口
*/
type SocketSource interface {
	Write(msg []byte) error
	Read(msg *[]byte) error
	Close() error
}

/*
Conn 实现 SocketSource 接口
*/
type Conn struct {
	c     net.Conn
	close chan int
}

/*
Write 实现 SocketSource 的Write方法
*/
func (c *Conn) Write(msg []byte) error {
	_, err := c.c.Write(msg)
	return err
}

/*
Read 实现 SocketSource 的Read方法
*/
func (c *Conn) Read(msg *[]byte) error {
	_, err := c.c.Read(*msg)
	return err
}

/*
Close 实现 SocketSource 的Close方法
*/
func (c *Conn) Close() error {
	err := c.c.Close()
	c.close <- 1
	return err
}

/*
worker 对请求进行处理, 后续可能增加限流
*/
func (c *Conn) worker(w *WebSocket) {
	var msg string
	buf := []byte{1}
	err := c.Write([]byte(w.hello + "\r\n"))
	if err != nil {
		panic(err)
	}
	for {
		select {
		case <-c.close:
			close(c.close)
			return
		default:
			_, err := c.c.Read(buf)
			if err != nil {
				fmt.Println("Read Client Msg Error!")
				err = c.c.Close()
				return
			}
			tmp := string(buf)
			if tmp != "\r" {
				msg = msg + tmp
			} else {
				msg = strings.TrimSpace(msg)
				w.CallBack(msg, c)
				msg = ""
			}
		}
	}
}

/*
NewWebSocket 返回一个新的 WebSocket 对象
*/
func NewWebSocket(hello string) *WebSocket {
	return &WebSocket{hello: hello}
}

/*
Handle 设置监听回调
*/
func (c *WebSocket) Handle(callback func(msg string, c *Conn)) {
	c.CallBack = callback
}

/*
Run 方法实现 Net 的listen
*/
func (c *WebSocket) Run(addr string) {
	ln, err := net.Listen("tcp", addr)
	if err != nil {
		panic("Listen To " + addr + " Failed!")
	}
	for {
		fd, err := ln.Accept()
		if err != nil {
			panic("Create Client Conn Failed!")
		}
		process := &Conn{c: fd}
		go process.worker(c)
	}
}
